namespace GemBox.Spreadsheet
{
    using System;
    using System.Drawing;
    using System.IO;
    using System.Runtime.InteropServices;

    public class ExcelPicture
    {
        private AnchorCell anchorCopyBottomRightCell;
        private AnchorCell anchorCopyTopLeftCell;
        private AnchorCell bottomRightCell;
        private Rectangle boundingRectangle;
        internal const double ColumnWidthToOffsetScale = 270.0;
        private System.Drawing.Image image;
        private MemoryStream imageStream;
        private int index;
        private ExcelPictureCollection parent;
        private ExcelPictureFormat pictureFormat;
        private const double pixelToOffsetScale = 9078.0;
        private PositioningMode positioning;
        internal const double RowHeightToOffsetScale = 592.0;
        private AnchorCell topLeftCell;

        internal ExcelPicture(ExcelPictureCollection parent, int index, System.Drawing.Image image, Rectangle boundingRectangle)
        {
            this.parent = parent;
            this.index = index;
            this.image = image;
            this.boundingRectangle = boundingRectangle;
        }

        internal ExcelPicture(ExcelPictureCollection parent, int index, MemoryStream imageStream, ExcelPictureFormat format)
        {
            this.parent = parent;
            this.index = index;
            this.imageStream = imageStream;
            this.image = System.Drawing.Image.FromStream(imageStream);
            this.pictureFormat = format;
        }

        internal ExcelPicture(ExcelPictureCollection parent, int index, MemoryStream imageStream, Rectangle boundingRectangle, ExcelPictureFormat format)
        {
            this.parent = parent;
            this.index = index;
            this.imageStream = imageStream;
            this.boundingRectangle = boundingRectangle;
            this.image = System.Drawing.Image.FromStream(imageStream);
            this.pictureFormat = format;
        }

        public void Delete()
        {
            this.parent.DeleteInternal(this.index);
        }

        private static void GetAnchorIndexesAndOffsets(ExcelRowColumnCollectionBase colRowBase, int maxColumnsRows, int recStart, int recEnd, double extentToOffsetScale, out int startCellIndex, out int endCellIndex, out long startCellOffset, out long endCellOffset)
        {
            int index = 0;
            double num2 = 0.0;
            double num3 = 0.0;
            double num4 = recStart * 9078.0;
            double num5 = recEnd * 9078.0;
            startCellIndex = endCellIndex = 0;
            startCellOffset = endCellOffset = 0L;
            while (index < maxColumnsRows)
            {
                num3 = colRowBase.GetItem(index).Extent * extentToOffsetScale;
                if ((num4 - num2) < num3)
                {
                    startCellIndex = index;
                    startCellOffset = Convert.ToInt64((double) (num4 - num2));
                    break;
                }
                index++;
                num2 += num3;
            }
            while (index < maxColumnsRows)
            {
                num3 = colRowBase.GetItem(index).Extent * extentToOffsetScale;
                if ((num5 - num2) < num3)
                {
                    endCellIndex = index;
                    endCellOffset = Convert.ToInt64((double) (num5 - num2));
                    break;
                }
                index++;
                num2 += num3;
            }
            if (index == maxColumnsRows)
            {
                throw new SpreadsheetException("Rectangle isn't valid.");
            }
        }

        internal static ExcelPictureFormat GetExcelPictureFormatFromFileName(string filename)
        {
            switch (Path.GetExtension(filename).Substring(1).ToLower())
            {
                case "jpg":
                case "jpeg":
                    return ExcelPictureFormat.Jpeg;

                case "gif":
                    return ExcelPictureFormat.Gif;

                case "tif":
                case "tiff":
                    return ExcelPictureFormat.Tiff;

                case "emf":
                    return ExcelPictureFormat.Emf;

                case "exif":
                    return ExcelPictureFormat.Exif;

                case "ico":
                    return ExcelPictureFormat.Ico;

                case "wmf":
                    return ExcelPictureFormat.Wmf;

                case "bmp":
                    return ExcelPictureFormat.Bmp;
            }
            return ExcelPictureFormat.Png;
        }

        private Rectangle GetRectangleFromAnchor()
        {
            int num;
            int num2;
            int num3;
            int num4;
            ExcelWorksheet worksheet = this.parent.Worksheet;
            GetRectangleSizeAndPosition(worksheet.Columns, this.TopLeftCell.Column.Index, this.BottomRightCell.Column.Index, this.TopLeftCell.ColumnOffset, this.BottomRightCell.ColumnOffset, out num, out num3, 270.0);
            GetRectangleSizeAndPosition(worksheet.Rows, this.TopLeftCell.Row.Index, this.BottomRightCell.Row.Index, this.TopLeftCell.RowOffset, this.BottomRightCell.RowOffset, out num2, out num4, 592.0);
            return new Rectangle(num, num2, num3, num4);
        }

        private static void GetRectangleSizeAndPosition(ExcelRowColumnCollectionBase colRowBase, int startCellIndex, int endCellIndex, long startCellOffset, long endCellOffset, out int recStart, out int recSize, double extentToOffsetScale)
        {
            int index = 0;
            int num2 = 0;
            while (index < startCellIndex)
            {
                num2 += colRowBase.GetItem(index).Extent;
                index++;
            }
            recStart = Convert.ToInt32((double) (((num2 * extentToOffsetScale) + startCellOffset) / 9078.0));
            while (index < endCellIndex)
            {
                num2 += colRowBase.GetItem(index).Extent;
                index++;
            }
            int num3 = Convert.ToInt32((double) (((num2 * extentToOffsetScale) + endCellOffset) / 9078.0));
            recSize = num3 - recStart;
        }

        internal void SetAnchor(PositioningMode mode, AnchorCell topLeftCell, AnchorCell bottomRightCell)
        {
            string str = "Anchor cells are not valid. ";
            if ((topLeftCell.Column.Index > bottomRightCell.Column.Index) || (topLeftCell.Row.Index > bottomRightCell.Row.Index))
            {
                throw new SpreadsheetException(str + "Top left cell can't have smaller column or row index then bottom right cell.");
            }
            if ((topLeftCell.Column.Index == bottomRightCell.Column.Index) && (topLeftCell.ColumnOffset > bottomRightCell.ColumnOffset))
            {
                throw new SpreadsheetException(str + "If both cells are in the same column, top left cell can't have smaller column offset then bottom right cell.");
            }
            if ((topLeftCell.Row.Index == bottomRightCell.Row.Index) && (topLeftCell.RowOffset > bottomRightCell.RowOffset))
            {
                throw new SpreadsheetException(str + "If both cells are in the same row, top left cell can't have smaller row offset then bottom right cell.");
            }
            this.Positioning = mode;
            this.TopLeftCell = topLeftCell;
            this.BottomRightCell = bottomRightCell;
        }

        internal void SetAnchorFromRectangle()
        {
            int num;
            int num2;
            long num3;
            long num4;
            Rectangle rectangle = new Rectangle(this.BoundingRectangle.Location, this.BoundingRectangle.Size);
            this.TopLeftCell = new AnchorCell();
            this.BottomRightCell = new AnchorCell();
            ExcelWorksheet worksheet = this.parent.Worksheet;
            GetAnchorIndexesAndOffsets(worksheet.Columns, 0x4000, rectangle.Left, rectangle.Right, 270.0, out num, out num2, out num3, out num4);
            this.TopLeftCell.Column = worksheet.Columns[num];
            this.BottomRightCell.Column = worksheet.Columns[num2];
            this.TopLeftCell.ColumnOffset = num3;
            this.BottomRightCell.ColumnOffset = num4;
            GetAnchorIndexesAndOffsets(worksheet.Rows, 0x100000, rectangle.Top, rectangle.Bottom, 592.0, out num, out num2, out num3, out num4);
            this.TopLeftCell.Row = worksheet.Rows[num];
            this.BottomRightCell.Row = worksheet.Rows[num2];
            this.TopLeftCell.RowOffset = num3;
            this.BottomRightCell.RowOffset = num4;
        }

        public AnchorCell BottomRightCell
        {
            get
            {
                return this.bottomRightCell;
            }
            set
            {
                this.bottomRightCell = value;
            }
        }

        public Rectangle BoundingRectangle
        {
            get
            {
                if (!object.Equals(this.anchorCopyTopLeftCell, this.TopLeftCell) || !object.Equals(this.anchorCopyBottomRightCell, this.BottomRightCell))
                {
                    this.boundingRectangle = this.GetRectangleFromAnchor();
                    this.anchorCopyTopLeftCell = new AnchorCell(this.TopLeftCell);
                    this.anchorCopyBottomRightCell = new AnchorCell(this.BottomRightCell);
                }
                return this.boundingRectangle;
            }
        }

        public System.Drawing.Image Image
        {
            get
            {
                return this.image;
            }
        }

        public MemoryStream ImageStream
        {
            get
            {
                return this.imageStream;
            }
        }

        internal int Index
        {
            get
            {
                return this.index;
            }
            set
            {
                this.index = value;
            }
        }

        public ExcelPictureFormat PictureFormat
        {
            get
            {
                return this.pictureFormat;
            }
        }

        public PositioningMode Positioning
        {
            get
            {
                return this.positioning;
            }
            set
            {
                this.positioning = value;
            }
        }

        public AnchorCell TopLeftCell
        {
            get
            {
                return this.topLeftCell;
            }
            set
            {
                this.topLeftCell = value;
            }
        }
    }
}
